#pragma once
#include"Common.h"

template<class T>
class ObjectPool
{
public:
	//申请空间
	T* New()
	{
		T* obj = nullptr;
		// 如果⾃由链表有对象，直接取⼀个
		if (_freeList)
		{
			obj = (T*)_freeList;
			_freeList = *((void**)_freeList);
		}
		else//自由链表为空，需要向内存池申请
		{
			//如果内存池空间不足，需要向堆申请
			if (_remainBytes < sizeof(T))
			{
				_remainBytes = 128 * 1024;
				//_memory = (char*)malloc(_remainBytes);
				_memory = (char*)SystemAlloc(_remainBytes >> 13);
				if (_memory == nullptr)//申请失败，报错
				{
					throw std::bad_alloc();
				}
			}
			obj = (T*)_memory;
			//避免内存池申请时是win32，返回需要win64得内存分配不足得窘境
			size_t objSize = sizeof(T) < sizeof(void*) ? sizeof(void*) :
				sizeof(T);
			_memory += objSize;
			_remainBytes -= objSize;
		}
		//显示定位new，调用它的构造函数及进行初始化对象
		new(obj)T;

		return obj;
	}
	//将用完的内存块存放起来
	void Delete(T* obj)
	{
		// 显⽰调⽤的T的析构函数进⾏清理
		obj->~T();
		// 头插到freeList
		*((void**)obj) = _freeList;
		_freeList = obj;
	}
private:
	char* _memory = nullptr; // 指向内存块的指针
	size_t _remainBytes = 0; // 内存块中剩余字节数
	void* _freeList = nullptr; // 管理还回来的内存对象的⾃由链表
};